home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * Copyright 1991 © SuperMac Technologies
- * All Rights Reserved
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SuperMac Technologies
- * The copyright notice above does not evidence any
- * actual or intended publication of such source code.
- *
- */
- /*------------------------------------------------------------------------------
- #
- # Apple Macintosh Developer Technical Support
- #
- # MultiFinder-Aware Simple Sample Application
- #
- # Sample
- #
- # Sample.c - C Source
- #
- # Copyright © 1988 Apple Computer, Inc.
- # All rights reserved.
- #
- # Versions: 1.0 08/88
- # 1.01 11/88
- #
- # Components: Sample.p November 1, 1988
- # Sample.c November 1, 1988
- # Sample.a November 1, 1988
- # Sample.inc1.a November 1, 1988
- # SampleMisc.a November 1, 1988
- # Sample.r November 1, 1988
- # Sample.h November 1, 1988
- # [A]Sample.make November 1, 1988
- # [C]Sample.make November 1, 1988
- # [P]Sample.make November 1, 1988
- #
- # Sample is an example application that demonstrates how to
- # initialize the commonly used toolbox managers, operate
- # successfully under MultiFinder, handle desk accessories,
- # and create, grow, and zoom windows.
- #
- # It does not by any means demonstrate all the techniques
- # you need for a large application. In particular, Sample
- # does not cover exception handling, multiple windows/documents,
- # sophisticated memory management, printing, or undo. All of
- # these are vital parts of a normal full-sized application.
- #
- # This application is an example of the form of a Macintosh
- # application; it is NOT a template. It is NOT intended to be
- # used as a foundation for the next world-class, best-selling,
- # 600K application. A stick figure drawing of the human body may
- # be a good example of the form for a painting, but that does not
- # mean it should be used as the basis for the next Mona Lisa.
- #
- # We recommend that you review this program or TESample before
- # beginning a new application.
- #
- ------------------------------------------------------------------------------*/
-
-
- /* Segmentation strategy:
-
- This program consists of three segments. Main contains most of the code,
- including the MPW libraries, and the main program. Initialize contains
- code that is only used once, during startup, and can be unloaded after the
- program starts. %A5Init is automatically created by the Linker to initialize
- globals for the MPW libraries and is unloaded right away. */
-
-
- /* SetPort strategy:
-
- Toolbox routines do not change the current port. In spite of this, in this
- program we use a strategy of calling SetPort whenever we want to draw or
- make calls which depend on the current port. This makes us less vulnerable
- to bugs in other software which might alter the current port (such as the
- bug (feature?) in many desk accessories which change the port on OpenDeskAcc).
- Hopefully, this also makes the routines from this program more self-contained,
- since they don't depend on the current port setting. */
-
-
- #include <Limits.h>
- #include <Types.h>
- #include <Resources.h>
- #include <QuickDraw.h>
- #include <Fonts.h>
- #include <Events.h>
- #include <Windows.h>
- #include <Menus.h>
- #include <TextEdit.h>
- #include <Dialogs.h>
- #include <Desk.h>
- #include <ToolUtils.h>
- #include <Memory.h>
- #include <SegLoad.h>
- #include <Files.h>
- #include <OSUtils.h>
- #include <Traps.h>
- #include <qdoffscreen.h>
- #include <standardfile.h>
- #include <Sample.h> /* bring in all the #defines for Sample */
-
- short xoff = 20;
- short yoff = 60;
-
- long convolved = 0;
-
- struct x{
- GWorldPtr gwp;
- Rect rect;
- ControlHandle hScroll;
- ControlHandle vScroll;
- short dx;
- short dy;
- };
-
- typedef struct x **xhandle;
-
- short picrefnum;
-
- ControlHandle theControl;
-
- short newvalue;
-
- Ptr buffer;
- long bleft;
- Ptr bptr;
- #define BSIZE 8192
-
- /* The "g" prefix is used to emphasize that a variable is global. */
-
- /* GMac is used to hold the result of a SysEnvirons call. This makes
- it convenient for any routine to check the environment. */
- SysEnvRec gMac; /* set up by Initialize */
-
- /* GHasWaitNextEvent is set at startup, and tells whether the WaitNextEvent
- trap is available. If it is false, we know that we must call GetNextEvent. */
- Boolean gHasWaitNextEvent; /* set up by Initialize */
-
- /* GInBackground is maintained by our osEvent handling routines. Any part of
- the program can check it to find out if it is currently in the background. */
- Boolean gInBackground; /* maintained by Initialize and DoEvent */
-
-
- /* Here are declarations for all of the C routines. In MPW 3.0 we can use
- actual prototypes for parameter type checking. */
- void EventLoop( void );
- void DoEvent( EventRecord *event );
- void AdjustCursor( Point mouse, RgnHandle region );
- void DoUpdate( WindowPtr window );
- void DoActivate( WindowPtr window, Boolean becomingActive );
- void DoContentClick( WindowPtr window, EventRecord *event );
- void DrawWindow( WindowPtr window );
- void AdjustMenus( void );
- void DoMenuCommand( long menuResult );
- Boolean DoCloseWindow( WindowPtr window );
- void Terminate( void );
- void Initialize( void );
- void ForceEnvirons( void );
- Boolean IsAppWindow( WindowPtr window );
- Boolean IsDAWindow( WindowPtr window );
- Boolean TrapAvailable( short tNumber, TrapType tType );
- void AlertUser( void );
-
-
- /* Define HiWrd and LoWrd macros for efficiency. */
- #define HiWrd(aLong) (((aLong) >> 16) & 0xFFFF)
- #define LoWrd(aLong) ((aLong) & 0xFFFF)
-
- /* Define TopLeft and BotRight macros for convenience. Notice the implicit
- dependency on the ordering of fields within a Rect */
- #define TopLeft(aRect) (* (Point *) &(aRect).top)
- #define BotRight(aRect) (* (Point *) &(aRect).bottom)
-
-
- extern void _DataInit();
-
- /* This routine is part of the MPW runtime library. This external
- reference to it is done so that we can unload its segment, %A5Init. */
-
-
- #pragma segment Main
- main()
- {
- UnloadSeg((Ptr) _DataInit); /* note that _DataInit must not be in Main! */
-
- /* 1.01 - call to ForceEnvirons removed */
-
- /* If you have stack requirements that differ from the default,
- then you could use SetApplLimit to increase StackSpace at
- this point, before calling MaxApplZone. */
- SetApplLimit(GetApplLimit()-(64*1024));
- MaxApplZone(); /* expand the heap so code segments load at the top */
-
- Initialize(); /* initialize the program */
- UnloadSeg((Ptr) Initialize); /* note that Initialize must not be in Main! */
-
- EventLoop(); /* call the main event loop */
- }
-
-
- /* Get events forever, and handle them by calling DoEvent.
- Get the events by calling WaitNextEvent, if it's available, otherwise
- by calling GetNextEvent. Also call AdjustCursor each time through the loop. */
-
- #pragma segment Main
- void EventLoop()
- {
- RgnHandle cursorRgn;
- Boolean gotEvent;
- EventRecord event;
-
- cursorRgn = NewRgn(); /* we’ll pass WNE an empty region the 1st time thru */
- do {
- /* use WNE if it is available */
- if ( gHasWaitNextEvent )
- gotEvent = WaitNextEvent(everyEvent, &event, LONG_MAX, cursorRgn);
- else {
- SystemTask();
- gotEvent = GetNextEvent(everyEvent, &event);
- }
- if ( gotEvent ) {
- /* make sure we have the right cursor before handling the event */
- AdjustCursor(event.where, cursorRgn);
- DoEvent(&event);
- }
- /* change the cursor (and region) if necessary */
- AdjustCursor(event.where, cursorRgn);
- } while ( true ); /* loop forever; we quit via ExitToShell */
- } /*EventLoop*/
-
-
- /* Calculate the new control maximum value and current value, whether it is the horizontal or
- vertical scrollbar. The vertical max is calculated by comparing the number of lines to the
- vertical size of the viewRect. The horizontal max is calculated by comparing the maximum document
- width to the width of the viewRect. The current values are set by comparing the offset between
- the view and destination rects. If necessary and we canRedraw, have the control be re-drawn by
- calling ShowControl. */
-
- #pragma segment Main
- void AdjustHV(isVert,control,window,canRedraw)
- Boolean isVert;
- ControlHandle control;
- WindowPtr window;
- Boolean canRedraw;
- {
- short value, max;
- short oldValue, oldMax;
- xhandle xh;
-
- xh = (xhandle)GetWRefCon(window);
- if (xh == NULL)
- return;
-
- oldValue = GetCtlValue(control);
- oldMax = GetCtlMax(control);
- if ( isVert ) {
- max = (*xh)->rect.bottom - (window->portRect.bottom-window->portRect.top - kScrollbarAdjust);
- } else
- max = (*xh)->rect.right - (window->portRect.right-window->portRect.left - kScrollbarAdjust);
-
- if ( max < 0 ) max = 0;
- SetCtlMax(control, max);
-
- if ( isVert )
- value = window->portRect.top;
- else
- value = window->portRect.left;
-
- if ( value < 0 ) value = 0;
- else if ( value > max ) value = max;
-
- if ( isVert )
- (*xh)->dy = value;
- else
- (*xh)->dx = value;
-
- SetCtlValue(control, value);
- /* now redraw the control if it needs to be and can be */
- if ( canRedraw || (max != oldMax) || (value != oldValue) )
- ShowControl(control);
- } /*AdjustHV*/
-
- /* Simply call the common adjust routine for the vertical and horizontal scrollbars. */
-
- #pragma segment Main
- void AdjustScrollValues(window,canRedraw)
- WindowPtr window;
- Boolean canRedraw;
- {
- xhandle xh;
-
- xh = (xhandle)GetWRefCon(window);
- if (xh == NULL)
- return;
- AdjustHV(true, (*xh)->vScroll, window, canRedraw);
- AdjustHV(false, (*xh)->hScroll, window, canRedraw);
- } /*AdjustScrollValues*/
-
- #pragma segment Main
- void AdjustScrollSizes(window)
- WindowPtr window;
- {
- xhandle xh;
-
- xh = (xhandle)GetWRefCon(window);
- if (xh == NULL)
- return;
-
- MoveControl((*xh)->vScroll, window->portRect.right - kScrollbarAdjust, -1);
- SizeControl((*xh)->vScroll, kScrollbarWidth, (window->portRect.bottom -
- window->portRect.top) - (kScrollbarAdjust - kScrollTweek));
- MoveControl((*xh)->hScroll, -1, window->portRect.bottom - kScrollbarAdjust);
- SizeControl((*xh)->hScroll, (window->portRect.right -
- window->portRect.left) - (kScrollbarAdjust - kScrollTweek),
- kScrollbarWidth);
- } /*AdjustScrollSizes*/
-
-
- /* Turn off the controls by jamming a zero into their contrlVis fields (HideControl erases them
- and we don't want that). If the controls are to be resized as well, call the procedure to do that,
- then call the procedure to adjust the maximum and current values. Finally re-enable the controls
- by jamming a $FF in their contrlVis fields. */
-
- #pragma segment Main
- void AdjustScrollbars(window,needsResize)
- WindowPtr window;
- Boolean needsResize;
- {
- xhandle xh;
-
- xh = (xhandle)GetWRefCon(window);
- if (xh == NULL)
- return;
- /* First, turn visibility of scrollbars off so we won’t get unwanted redrawing */
- (*(*xh)->vScroll)->contrlVis = kControlInvisible; /* turn them off */
- (*(*xh)->hScroll)->contrlVis = kControlInvisible;
- if ( needsResize ) /* move & size as needed */
- AdjustScrollSizes(window);
- AdjustScrollValues(window, needsResize); /* fool with max and current value */
- /* Now, restore visibility in case we never had to ShowControl during adjustment */
- (*(*xh)->vScroll)->contrlVis = kControlVisible; /* turn them on */
- (*(*xh)->hScroll)->contrlVis = kControlVisible;
- } /* AdjustScrollbars */
-
- /* Called when the window has been resized to fix up the controls and content. */
- #pragma segment Main
- void ResizeWindow(window)
- WindowPtr window;
- {
- AdjustScrollbars(window, true);
- InvalRect(&window->portRect);
- } /* ResizeWindow */
-
-
- /* Called when a mouseDown occurs in the grow box of an active window. In
- order to eliminate any 'flicker', we want to invalidate only what is
- necessary. Since ResizeWindow invalidates the whole portRect, we save
- the old TE viewRect, intersect it with the new TE viewRect, and
- remove the result from the update region. However, we must make sure
- that any old update region that might have been around gets put back. */
-
- #pragma segment Main
- void DoGrowWindow(window,event)
- WindowPtr window;
- EventRecord *event;
- {
- long growResult;
- Rect tempRect;
- xhandle xh;
-
- xh = (xhandle)GetWRefCon(window);
- if (xh == NULL)
- return;
- SetPort(window);
- tempRect = (*xh)->rect;
- tempRect.left = 64;
- tempRect.top = 64;
- tempRect.right += kScrollbarWidth;
- tempRect.bottom += kScrollbarWidth;
- growResult = GrowWindow(window, event->where, &tempRect);
- /* see if it really changed size */
- if ( growResult != 0 ) {
- SizeWindow(window, LoWrd(growResult), HiWrd(growResult), true);
- ResizeWindow(window);
- }
- } /* DoGrowWindow */
-
- /* Do the right thing for an event. Determine what kind of event it is, and call
- the appropriate routines. */
-
- #pragma segment Main
- void DoEvent(event)
- EventRecord *event;
- {
- short part;
- WindowPtr window;
- Boolean hit;
- char key;
- Point p;
- xhandle xh;
- Rect r;
-
- switch ( event->what ) {
- case mouseDown:
- part = FindWindow(event->where, &window);
- switch ( part ) {
- case inMenuBar: /* process a mouse menu command (if any) */
- AdjustMenus();
- DoMenuCommand(MenuSelect(event->where));
- break;
- case inSysWindow: /* let the system handle the mouseDown */
- SystemClick(event, window);
- break;
- case inContent:
- if ( window != FrontWindow() ) {
- SelectWindow(window);
- /*DoEvent(event);*/ /* use this line for "do first click" */
- } else
- DoContentClick(window, event);
- break;
- case inDrag: /* pass screenBits.bounds to get all gDevices */
- if ( window != FrontWindow() )
- SelectWindow(window);
- DragWindow(window, event->where, &qd.screenBits.bounds);
- xoff = 20;
- yoff = 40;
- break;
- case inGrow:
- DoGrowWindow(window, event);
- break;
- case inGoAway:
- if ( TrackGoAway(window, event->where) )
- DoCloseWindow(window); /* we don’t care if the user cancelled */
- break;
- case inZoomIn:
- case inZoomOut:
- SetPort(window); /* the window must be the current port... */
- hit = TrackBox(window, event->where, part);
- if ( hit ) {
- SetPort(window); /* the window must be the current port... */
- p.h = 0;
- p.v = 0;
- LocalToGlobal(&p);
- xh = (xhandle)GetWRefCon(window);
- r = (*xh)->rect;
- r.left += p.h;
- r.right += p.h + kScrollbarAdjust;
- r.top += p.v;
- r.bottom += p.v + kScrollbarAdjust;
- (*(WStateDataHandle)(((WindowPeek)window)->dataHandle))->stdState = r;
- /* EraseRect(&window->portRect); /* because of a bug in ZoomWindow */
- ZoomWindow(window, part, true); /* note that we invalidate and erase... */
- ResizeWindow(window);
- }
- break;
- }
- break;
- case keyDown:
- case autoKey: /* check for menukey equivalents */
- key = event->message & charCodeMask;
- if ( event->modifiers & cmdKey ) /* Command key down */
- if ( event->what == keyDown ) {
- AdjustMenus(); /* enable/disable/check menu items properly */
- DoMenuCommand(MenuKey(key));
- }
- break;
- case activateEvt:
- DoActivate((WindowPtr) event->message, (event->modifiers & activeFlag) != 0);
- break;
- case updateEvt:
- DoUpdate((WindowPtr) event->message);
- break;
- case kOSEvent:
- switch (event->message >> 24) { /* high byte of message */
- case kSuspendResumeMessage: /* suspend/resume is also an activate/deactivate */
- gInBackground = (event->message & kResumeMask) == 0;
- DoActivate(FrontWindow(), !gInBackground);
- break;
- }
- break;
- }
- } /*DoEvent*/
-
-
- /* Change the cursor's shape, depending on its position. This also calculates the region
- where the current cursor resides (for WaitNextEvent). If the mouse is ever outside of
- that region, an event would be generated, causing this routine to be called,
- allowing us to change the region to the region the mouse is currently in. If
- there is more to the event than just “the mouse moved”, we get called before the
- event is processed to make sure the cursor is the right one. In any (ahem) event,
- this is called again before we fall back into WNE. */
-
- #pragma segment Main
- void AdjustCursor(mouse,region)
- Point mouse;
- RgnHandle region;
- {
- WindowPtr window;
-
- window = FrontWindow(); /* we only adjust the cursor when we are in front */
- if ( (! gInBackground) && (! IsDAWindow(window)) ) {
- SetCursor(&qd.arrow);
- }
- } /*AdjustCursor*/
-
-
- /* This is called when an update event is received for a window.
- It calls DrawWindow to draw the contents of an application window.
- As an effeciency measure that does not have to be followed, it
- calls the drawing routine only if the visRgn is non-empty. This
- will handle situations where calculations for drawing or drawing
- itself is very time-consuming. */
-
- #pragma segment Main
- void DoUpdate(window)
- WindowPtr window;
- {
- if ( IsAppWindow(window) ) {
- BeginUpdate(window); /* this sets up the visRgn */
- if ( ! EmptyRgn(window->visRgn) ) /* draw if updating needs to be done */
- DrawWindow(window);
- EndUpdate(window);
- }
- } /*DoUpdate*/
-
-
- /* This is called when a window is activated or deactivated.
- In Sample, the Window Manager's handling of activate and
- deactivate events is sufficient. Other applications may have
- TextEdit records, controls, lists, etc., to activate/deactivate. */
-
- #pragma segment Main
- void DoActivate(window, becomingActive)
- WindowPtr window;
- Boolean becomingActive;
- {
- Rect growRect;
- xhandle xh;
-
- xh = (xhandle)GetWRefCon(window);
- if ( IsAppWindow(window) ) {
- SetPort(window);
- if ( becomingActive ) {
-
- /* the controls must be redrawn on activation: */
- (*(*xh)->vScroll)->contrlVis = kControlVisible;
- (*(*xh)->hScroll)->contrlVis = kControlVisible;
- InvalRect(&(*(*xh)->vScroll)->contrlRect);
- InvalRect(&(*(*xh)->hScroll)->contrlRect);
- /* the growbox needs to be redrawn on activation: */
- growRect = window->portRect;
- /* adjust for the scrollbars */
- growRect.top = growRect.bottom - kScrollbarAdjust;
- growRect.left = growRect.right - kScrollbarAdjust;
- InvalRect(&growRect);
- }
- else {
- /* the controls must be hidden on deactivation: */
- HideControl((*xh)->vScroll);
- HideControl((*xh)->hScroll);
- /* the growbox should be changed immediately on deactivation: */
- DrawGrowIcon(window);
- }
- }
- } /*DoActivate*/
-
-
- /* Common algorithm for pinning the value of a control. It returns the actual amount
- the value of the control changed. Note the pinning is done for the sake of returning
- the amount the control value changed. */
-
- #pragma segment Main
- void CommonAction(control,amount)
- ControlHandle control;
- short *amount;
- {
- short value, max;
-
- value = GetCtlValue(control); /* get current value */
- max = GetCtlMax(control); /* and maximum value */
- *amount = value - *amount;
- if ( *amount < 0 )
- *amount = 0;
- else if ( *amount > max )
- *amount = max;
- SetCtlValue(control, *amount);
- *amount = value - *amount; /* calculate the real change */
- } /* CommonAction */
-
- #pragma segment Main
- pascal void VActionProc(control,part)
- ControlHandle control;
- short part;
- {
- short amount;
- WindowPtr window;
- Rect r1, r2;
- xhandle xh;
-
- if ( part != 0 ) { /* if it was actually in the control */
- window = (*control)->contrlOwner;
- switch ( part ) {
- case inUpButton:
- case inDownButton: /* one line */
- amount = 10;
- break;
- case inPageUp: /* one page */
- case inPageDown:
- amount = window->portRect.bottom-window->portRect.top-kScrollbarAdjust;
- break;
- }
- if ( (part == inDownButton) || (part == inPageDown) )
- amount = -amount; /* reverse direction for a downer */
- CommonAction(control, &amount);
- if (amount == 0)
- return;
- xh = (xhandle)GetWRefCon(window);
- (*xh)->dy += amount;
- r1 = window->portRect;
- r1.right -= kScrollbarAdjust;
- r1.bottom -= kScrollbarAdjust;
- r2 = r1;
- if (amount > 0) {
- r1.bottom -= amount;
- r2.top += amount;
- } else {
- r2.bottom += amount;
- r1.top -= amount;
- }
- if (r1.top < r1.bottom) {
- CopyBits((BitMap *)&qd.thePort->portBits, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- if (amount > 0) {
- r2.top = r1.top;
- r2.bottom -= 1;
- } else {
- r2.bottom = r1.bottom;
- r2.top += 1;
- }
- r1.left -= (*xh)->dx;
- r1.right -= (*xh)->dx;
- r1.top = r2.top - (*xh)->dy;
- r1.bottom = r2.bottom - (*xh)->dy;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- } else {
- r2 = window->portRect;
- r2.right -= kScrollbarAdjust;
- r2.bottom -= kScrollbarAdjust;
- r1 = r2;
- r1.left -= (*xh)->dx;
- r1.right -= (*xh)->dx;
- r1.top -= (*xh)->dy;
- r1.bottom -= (*xh)->dy;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- }
- }
- } /* VActionProc */
-
-
- pascal void HActionProc(control,part)
- ControlHandle control;
- short part;
- {
- short amount;
- WindowPtr window;
- Rect r1, r2;
- xhandle xh;
-
- if ( part != 0 ) { /* if it was actually in the control */
- window = (*control)->contrlOwner;
- switch ( part ) {
- case inUpButton:
- case inDownButton: /* one line */
- amount = 10;
- break;
- case inPageUp: /* one page */
- case inPageDown:
- amount = window->portRect.right-window->portRect.left-kScrollbarAdjust;
- break;
- }
- if ( (part == inDownButton) || (part == inPageDown) )
- amount = -amount; /* reverse direction for a downer */
- CommonAction(control, &amount);
- if (amount == 0)
- return;
- xh = (xhandle)GetWRefCon(window);
- (*xh)->dx += amount;
- r1 = window->portRect;
- r1.right -= kScrollbarAdjust;
- r1.bottom -= kScrollbarAdjust;
- r2 = r1;
- if (amount > 0) {
- r1.right -= amount;
- r2.left += amount;
- } else {
- r2.right += amount;
- r1.left -= amount;
- }
- if (r1.left < r1.right) {
- CopyBits((BitMap *)&qd.thePort->portBits, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- if (amount > 0) {
- r2.left = r1.left;
- r2.right -= 1;
- } else {
- r2.right = r1.right;
- r2.left += 1;
- }
- r1.top -= (*xh)->dy;
- r1.bottom -= (*xh)->dy;
- r1.left = r2.left - (*xh)->dx;
- r1.right = r2.right - (*xh)->dx;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- } else {
- r2 = window->portRect;
- r2.right -= kScrollbarAdjust;
- r2.bottom -= kScrollbarAdjust;
- r1 = r2;
- r1.left -= (*xh)->dx;
- r1.right -= (*xh)->dx;
- r1.top -= (*xh)->dy;
- r1.bottom -= (*xh)->dy;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- }
- }
- } /* HActionProc */
-
-
- #pragma segment Main
- pascal void SVActionProc()
- {
- ControlHandle control;
- short amount, value;
- WindowPtr window;
- Rect r1, r2;
- xhandle xh;
- Point p;
-
- control = theControl;
- window = (*control)->contrlOwner;
-
- GetMouse(&p);
- r1 = (*control)->contrlRect;
- r1.top += 16;
- r1.bottom -= 16;
- if (p.v < r1.top) {
- p.v = r1.top;
- } else
- if (p.v > r1.bottom)
- p.v = r1.bottom;
-
- xh = (xhandle)GetWRefCon(window);
-
- amount = (short)(((float)((*xh)->rect.bottom-(*xh)->rect.top - (window->portRect.bottom-window->portRect.top-kScrollbarAdjust))) *
- ((float)(p.v-r1.top))/((float)(r1.bottom-r1.top)));
-
- if ( amount < 0 )
- amount = 0;
- if (newvalue == amount)
- return;
- value = newvalue;
- newvalue = amount;
- amount = value - amount;
-
- (*xh)->dy += amount;
- r1 = window->portRect;
- r1.right -= kScrollbarAdjust;
- r1.bottom -= kScrollbarAdjust;
- r2 = r1;
- if (amount > 0) {
- r1.bottom -= amount;
- r2.top += amount;
- } else {
- r2.bottom += amount;
- r1.top -= amount;
- }
- if (r1.top < r1.bottom) {
- CopyBits((BitMap *)&qd.thePort->portBits, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- if (amount > 0) {
- r2.top = r1.top;
- } else {
- r2.bottom = r1.bottom;
- }
- r1.left -= (*xh)->dx;
- r1.right -= (*xh)->dx;
- r1.top = r2.top - (*xh)->dy;
- r1.bottom = r2.bottom - (*xh)->dy;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- } else {
- r2 = window->portRect;
- r2.right -= kScrollbarAdjust;
- r2.bottom -= kScrollbarAdjust;
- r1 = r2;
- r1.left -= (*xh)->dx;
- r1.right -= (*xh)->dx;
- r1.top -= (*xh)->dy;
- r1.bottom -= (*xh)->dy;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- }
- } /* HActionProc */
-
-
- #pragma segment Main
- pascal void SHActionProc()
- {
- ControlHandle control;
- short amount, value;
- WindowPtr window;
- Rect r1, r2;
- xhandle xh;
- Point p;
-
- control = theControl;
- window = (*control)->contrlOwner;
-
- GetMouse(&p);
- r1 = (*control)->contrlRect;
- r1.left += 16;
- r1.right -= 16;
- if (p.h < r1.left) {
- p.h = r1.left;
- } else
- if (p.h > r1.right)
- p.h = r1.right;
-
- xh = (xhandle)GetWRefCon(window);
-
- amount = (short)(((float)((*xh)->rect.right-(*xh)->rect.left - (window->portRect.right-window->portRect.left-kScrollbarAdjust))) *
- ((float)(p.h-r1.left))/((float)(r1.right-r1.left)));
-
- if ( amount < 0 )
- amount = 0;
- if (newvalue == amount)
- return;
- value = newvalue;
- newvalue = amount;
- amount = value - amount;
-
- (*xh)->dx += amount;
- r1 = window->portRect;
- r1.right -= kScrollbarAdjust;
- r1.bottom -= kScrollbarAdjust;
- r2 = r1;
- if (amount > 0) {
- r1.right -= amount;
- r2.left += amount;
- } else {
- r2.right += amount;
- r1.left -= amount;
- }
- if (r1.left < r1.right) {
- CopyBits((BitMap *)&qd.thePort->portBits, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- if (amount > 0) {
- r2.left = r1.left;
- r2.right -= 1;
- } else {
- r2.right = r1.right;
- r2.left += 1;
- }
- r1.top -= (*xh)->dy;
- r1.bottom -= (*xh)->dy;
- r1.left = r2.left - (*xh)->dx;
- r1.right = r2.right - (*xh)->dx;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- } else {
- r2 = window->portRect;
- r2.right -= kScrollbarAdjust;
- r2.bottom -= kScrollbarAdjust;
- r1 = r2;
- r1.left -= (*xh)->dx;
- r1.right -= (*xh)->dx;
- r1.top -= (*xh)->dy;
- r1.bottom -= (*xh)->dy;
- CopyBits((BitMap *)&(*xh)->gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- }
-
- } /* HActionProc */
-
-
- /* This is called when a mouse-down event occurs in the content of a window.
- Other applications might want to call FindControl, TEClick, etc., to
- further process the click. */
-
- #pragma segment Main
- void DoContentClick(window,event)
- WindowPtr window;
- EventRecord *event;
- {
- Point mouse;
- ControlHandle control;
- short part, value;
- xhandle xh;
-
- if ( IsAppWindow(window) ) {
- xh = (xhandle)GetWRefCon(window);
- SetPort(window);
- mouse = event->where; /* get the click position */
- GlobalToLocal(&mouse);
- part = FindControl(mouse, window, &control);
- switch ( part ) {
- case 0: /* do nothing for viewRect case */
- break;
- case inThumb:
- theControl = control;
- newvalue = GetCtlValue(control);
- if ( control == (*xh)->vScroll ) {
- value = TrackControl(control, mouse, (ProcPtr) SVActionProc);
- } else {
- value = TrackControl(control, mouse, (ProcPtr) SHActionProc);
- }
- SetCtlValue(control, newvalue);
- break;
- default: /* they clicked in an arrow, so track & scroll */
- if ( control == (*xh)->vScroll ) {
- value = TrackControl(control, mouse, (ProcPtr) VActionProc);
- } else {
- value = TrackControl(control, mouse, (ProcPtr) HActionProc);
- }
- break;
- }
- }
- } /*DoContentClick*/
-
-
- /* Draw the contents of the application window. We do some drawing in color, using
- Classic QuickDraw's color capabilities. This will be black and white on old
- machines, but color on color machines. At this point, the window’s visRgn
- is set to allow drawing only where it needs to be done. */
-
- #pragma segment Main
- void DrawWindow(window)
- WindowPtr window;
- {
- xhandle xhp;
- Rect r1, r2;
- GWorldPtr gwp;
- PixMapHandle pm;
-
- SetPort(window);
-
- DrawControls(window);
- DrawGrowIcon(window);
-
- xhp = (xhandle)GetWRefCon(window);
-
- if (xhp == NULL) {
- EraseRect(&window->portRect);
- return;
- }
-
- gwp = (*xhp)->gwp;
- if (gwp == NULL) {
- fail: EraseRect(&window->portRect);
- return;
- }
- r2 = window->portRect;
- r2.right -= kScrollbarAdjust;
- r2.bottom -= kScrollbarAdjust;
- r1 = r2;
- r1.left -= (*xhp)->dx;
- r1.right -= (*xhp)->dx;
- r1.top -= (*xhp)->dy;
- r1.bottom -= (*xhp)->dy;
- pm = GetGWorldPixMap(gwp);
- if (!LockPixels(pm))
- goto fail;
- CopyBits((BitMap *)&gwp->portPixMap, &qd.thePort->portBits, &r1, &r2, srcCopy, NULL);
- UnlockPixels(pm);
- } /*DrawWindow*/
-
-
- /* Enable and disable menus based on the current state.
- The user can only select enabled menu items. We set up all the menu items
- before calling MenuSelect or MenuKey, since these are the only times that
- a menu item can be selected. Note that MenuSelect is also the only time
- the user will see menu items. This approach to deciding what enable/
- disable state a menu item has the advantage of concentrating all
- the decision-making in one routine, as opposed to being spread throughout
- the application. Other application designs may take a different approach
- that is just as valid. */
-
- #pragma segment Main
- void AdjustMenus()
- {
- WindowPtr window;
- MenuHandle menu;
-
- window = FrontWindow();
-
- menu = GetMHandle(mFile);
- EnableItem(menu, iOpen);
- if ( window != NULL ) /* we can allow desk accessories to be closed from the menu */
- EnableItem(menu, iClose);
- else
- DisableItem(menu, iClose); /* but not our traffic light window */
-
- menu = GetMHandle(mEdit);
- if ( window != NULL && IsDAWindow(window) ) { /* a desk accessory might need the edit menu… */
- EnableItem(menu, iUndo);
- EnableItem(menu, iCut);
- EnableItem(menu, iCopy);
- EnableItem(menu, iClear);
- EnableItem(menu, iPaste);
- } else { /* …but we don’t use it */
- DisableItem(menu, iUndo);
- DisableItem(menu, iCut);
- DisableItem(menu, iCopy);
- DisableItem(menu, iClear);
- DisableItem(menu, iPaste);
- }
- menu = GetMHandle(mOptions);
- EnableItem(menu, iConvolve);
-
- } /*AdjustMenus*/
-
-
- /* This is called when an item is chosen from the menu bar (after calling
- MenuSelect or MenuKey). It performs the right operation for each command.
- It is good to have both the result of MenuSelect and MenuKey go to
- one routine like this to keep everything organized. */
-
- #pragma segment Main
- void DoMenuCommand(menuResult)
- long menuResult;
- {
- short menuID; /* the resource ID of the selected menu */
- short menuItem; /* the item number of the selected menu */
- short itemHit;
- Str255 daName;
- short daRefNum;
- Boolean handledByDA;
- SFReply reply;
- Point p;
- SFTypeList tp;
- PicHandle ph;
- long x;
- short err;
-
- menuID = HiWord(menuResult); /* use macros for efficiency to... */
- menuItem = LoWord(menuResult); /* get menu item number and menu number */
- switch ( menuID ) {
- case mApple:
- switch ( menuItem ) {
- case iAbout: /* bring up alert for About */
- itemHit = Alert(rAboutAlert, nil);
- break;
- default: /* all non-About items in this menu are DAs */
- /* type Str255 is an array in MPW 3 */
- GetItem(GetMHandle(mApple), menuItem, daName);
- daRefNum = OpenDeskAcc(daName);
- break;
- }
- break;
- case mFile:
- switch ( menuItem ) {
- case iOpen:
- p.v = 40;
- p.h = 40;
- tp[0] = 'PICT';
- SFGetFile(p, "\pPICT file:", NULL, 1, &tp, NULL, &reply);
- if (!reply.good)
- break;
- err = FSOpen(&reply.fName, reply.vRefNum, &picrefnum);
- if (err != noErr)
- break;
- ph = (PicHandle)NewHandle(sizeof(**ph));
- bptr = buffer = NewPtr(BSIZE);
- bleft = 0;
- err = SetFPos(picrefnum, fsFromStart, 512);
- HLock((Handle)ph);
- x = sizeof(**ph);
- err = FSRead(picrefnum, &x, (Ptr)*ph);
- MakeNewWindow(ph, &reply.fName);
- DisposeHandle((Handle)ph);
- if (buffer)
- DisposePtr(buffer);
- err = FSClose(picrefnum);
- break;
- case iClose:
- DoCloseWindow(FrontWindow());
- break;
- case iQuit:
- Terminate();
- break;
- }
- break;
- case mEdit: /* call SystemEdit for DA editing & MultiFinder */
- handledByDA = SystemEdit(menuItem-1); /* since we don’t do any Editing */
- break;
- case mOptions:
- switch ( menuItem ) {
- case iConvolve:
- convolved = 1-convolved;
- CheckItem(GetMHandle(mOptions), iConvolve, convolved);
- break;
- }
- break;
- }
- HiliteMenu(0); /* unhighlight what MenuSelect (or MenuKey) hilited */
- } /*DoMenuCommand*/
-
-
- /* Close a window. This handles desk accessory and application windows. */
-
- /* 1.01 - At this point, if there was a document associated with a
- window, you could do any document saving processing if it is 'dirty'.
- DoCloseWindow would return true if the window actually closed, i.e.,
- the user didn’t cancel from a save dialog. This result is handy when
- the user quits an application, but then cancels the save of a document
- associated with a window. */
-
- #pragma segment Main
- Boolean DoCloseWindow(window)
- WindowPtr window;
- {
- xhandle xh;
-
- if ( IsDAWindow(window) )
- CloseDeskAcc(((WindowPeek) window)->windowKind);
- else if ( IsAppWindow(window) ) {
- xh = (xhandle)GetWRefCon(window);
- if (xh) {
- if ((*xh)->gwp)
- DisposeGWorld((*xh)->gwp);
- DisposeHandle((Handle)xh);
- }
- CloseWindow(window);
- }
- return true;
- } /*DoCloseWindow*/
-
-
- /**************************************************************************************
- *** 1.01 DoCloseBehind(window) was removed ***
-
- 1.01 - DoCloseBehind was a good idea for closing windows when quitting
- and not having to worry about updating the windows, but it suffered
- from a fatal flaw. If a desk accessory owned two windows, it would
- close both those windows when CloseDeskAcc was called. When DoCloseBehind
- got around to calling DoCloseWindow for that other window that was already
- closed, things would go very poorly. Another option would be to have a
- procedure, GetRearWindow, that would go through the window list and return
- the last window. Instead, we decided to present the standard approach
- of getting and closing FrontWindow until FrontWindow returns NIL. This
- has a potential benefit in that the window whose document needs to be saved
- may be visible since it is the front window, therefore decreasing the
- chance of user confusion. For aesthetic reasons, the windows in the
- application should be checked for updates periodically and have the
- updates serviced.
- **************************************************************************************/
-
-
- /* Clean up the application and exit. We close all of the windows so that
- they can update their documents, if any. */
-
- /* 1.01 - If we find out that a cancel has occurred, we won't exit to the
- shell, but will return instead. */
-
- #pragma segment Main
- void Terminate()
- {
- WindowPtr aWindow;
- Boolean closed;
-
- closed = true;
- do {
- aWindow = FrontWindow(); /* get the current front window */
- if (aWindow != nil)
- closed = DoCloseWindow(aWindow); /* close this window */
- }
- while (closed && (aWindow != nil));
- if (closed)
- ExitToShell(); /* exit if no cancellation */
- } /*Terminate*/
-
-
- /* Set up the whole world, including global variables, Toolbox managers,
- and menus. We also create our one application window at this time.
- Since window storage is non-relocateable, how and when to allocate space
- for windows is very important so that heap fragmentation does not occur.
- Because Sample has only one window and it is only disposed when the application
- quits, we will allocate its space here, before anything that might be a locked
- relocatable object gets into the heap. This way, we can force the storage to be
- in the lowest memory available in the heap. Window storage can differ widely
- amongst applications depending on how many windows are created and disposed. */
-
- /* 1.01 - The code that used to be part of ForceEnvirons has been moved into
- this module. If an error is detected, instead of merely doing an ExitToShell,
- which leaves the user without much to go on, we call AlertUser, which puts
- up a simple alert that just says an error occurred and then calls ExitToShell.
- Since there is no other cleanup needed at this point if an error is detected,
- this form of error- handling is acceptable. If more sophisticated error recovery
- is needed, an exception mechanism, such as is provided by Signals, can be used. */
-
- #pragma segment Initialize
- void Initialize()
- {
- Handle menuBar;
- long total, contig;
- EventRecord event;
- short count;
-
- gHasWaitNextEvent = TrapAvailable(_WaitNextEvent, ToolTrap);
- gInBackground = false;
-
- InitGraf((Ptr) &qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
-
- /* Call MPPOpen and ATPLoad at this point to initialize AppleTalk,
- if you are using it. */
- /* NOTE -- It is no longer necessary, and actually unhealthy, to check
- PortBUse and SPConfig before opening AppleTalk. The drivers are capable
- of checking for port availability themselves. */
-
- /* Now this next bit of code may make you toss your cookies, but it is
- necessary to allow the default button of our alert be outlined. */
-
- for (count = 1; count <= 3; count++)
- GetNextEvent(everyEvent, &event);
-
- /* Ignore the error returned from SysEnvirons; even if an error occurred,
- the SysEnvirons glue will fill in the SysEnvRec. You can save a redundant
- call to SysEnvirons by calling it after initializing AppleTalk. */
-
- SysEnvirons(kSysEnvironsVersion, &gMac);
-
- /* Make sure that the machine has at least 128K ROMs. If it doesn't, exit. */
-
- if (gMac.machineType < 0) AlertUser();
-
- /* 1.01 - We used to make a check for memory at this point by examining ApplLimit,
- ApplicZone, and StackSpace and comparing that to the minimum size we told
- MultiFinder we needed. This did not work well because it assumed too much about
- the relationship between what we asked MultiFinder for and what we would actually
- get back, as well as how to measure it. Instead, we will use an alternate
- method comprised of two steps. */
-
- /* It is better to first check the size of the application heap against a value
- that you have determined is the smallest heap the application can reasonably
- work in. This number should be derived by examining the size of the heap that
- is actually provided by MultiFinder when the minimum size requested is used.
- The derivation of the minimum size requested from MultiFinder is described
- in Sample.h. The check should be made because the preferred size can end up
- being set smaller than the minimum size by the user. This extra check acts to
- insure that your application is starting from a solid memory foundation. */
-
- if ((long) GetApplLimit() - (long) ApplicZone() < kMinHeap) AlertUser();
-
- /* Next, make sure that enough memory is free for your application to run. It
- is possible for a situation to arise where the heap may have been of required
- size, but a large scrap was loaded which left too little memory. To check for
- this, call PurgeSpace and compare the result with a value that you have determined
- is the minimum amount of free memory your application needs at initialization.
- This number can be derived several different ways. One way that is fairly
- straightforward is to run the application in the minimum size configuration
- as described previously. Call PurgeSpace at initialization and examine the value
- returned. However, you should make sure that this result is not being modified
- by the scrap's presence. You can do that by calling ZeroScrap before calling
- PurgeSpace. Make sure to remove that call before shipping, though. */
-
- /* ZeroScrap(); */
-
- PurgeSpace(&total, &contig);
- if (total < kMinSpace) AlertUser();
-
- /* The extra benefit to waiting until after the Toolbox Managers have been initialized
- to check memory is that we can now give the user an alert to tell him/her what
- happened. Although it is possible that the memory situation could be worsened by
- displaying an alert, MultiFinder would gracefully exit the application with
- an informative alert if memory became critical. Here we are acting more
- in a preventative manner to avoid future disaster from low-memory problems. */
-
- /* we will allocate our own window storage instead of letting the Window
- Manager do it because GetNewWindow may load in temp. resources before
- making the NewPtr call, and this can lead to heap fragmentation. */
- menuBar = GetNewMBar(rMenuBar); /* read menus into menu bar */
- if ( menuBar == nil ) AlertUser();
- SetMenuBar(menuBar); /* install menus */
- DisposHandle(menuBar);
- AddResMenu(GetMHandle(mApple), 'DRVR'); /* add DA names to Apple menu */
- DrawMenuBar();
-
- } /*Initialize*/
-
- #pragma segment Main
- dprintf(char *s, long a, long b)
- {
- char xx[256];
-
- sprintf(&xx[1], s, a, b);
- xx[0] = strlen(&xx[1]);
- DebugStr(xx);
- }
-
- pascal
- GetPICTData(Ptr data, short count)
- {
- register long c1, c2;
- long c;
- register Ptr x1, x2;
-
- if (buffer == NULL) {
- c = count;
- (void)FSRead(picrefnum, &c, data);
- return;
- }
- x2 = data;
- c1 = count;
- for (;;) {
- if (bleft >= c1) {
- x1 = bptr;
- bleft -= c1;
- while (c1--)
- *x2++ = *x1++;
- bptr = x1;
- return;
- }
- if (c2 = bleft) {
- c1 -= c2;
- x1 = bptr;
- while (c2--)
- *x2++ = *x1++;
- }
- bptr = buffer;
- bleft = BSIZE;
- (void)FSRead(picrefnum, &bleft, bptr);
- }
- }
-
- #pragma segment Main
- MakeNewWindow(PicHandle ph, char *name)
- {
- WindowPtr window, window2;
- xhandle xh;
- Rect r, rg;
- GWorldPtr gwp;
- CQDProcs qdp;
- CGrafPtr oldgrp;
- GDHandle oldgd;
- PixMapHandle pm;
- char cc[70];
- long l;
- register long i, j, rb;
- register unsigned char *p, *base;
- char c;
-
- r = (*ph)->picFrame;
- r.right = r.right-r.left;
- r.bottom = r.bottom-r.top;
- r.left = 0;
- r.top = 0;
- rg.left = xoff;
- rg.right = xoff+r.right;
- rg.top = yoff;
- rg.bottom = yoff+r.bottom;
-
- GetGWorld(&oldgrp, &oldgd);
- if (NewGWorld(&gwp, 0, &rg, NULL, NULL, 0) != noErr)
- return(0);
-
- SetGWorld(gwp, NULL);
-
- SetStdCProcs(&qdp);
- gwp->grafProcs = &qdp;
- qdp.getPicProc = (Ptr)GetPICTData;
-
- pm = GetGWorldPixMap(gwp);
-
- (void)LockPixels(pm);
-
- DrawPicture(ph, &r);
-
- UnlockPixels(pm);
-
- l = (long)GetPixBaseAddr(pm);
-
- gwp->grafProcs = NULL;
- SetGWorld(oldgrp, oldgd);
- xh = (xhandle)NewHandle(sizeof(**xh));
- if (xh == NULL) {
- DisposeGWorld(gwp);
- return(0);
- }
- window = (WindowPtr) NewPtr(sizeof(WindowRecord));
- if (window == NULL) {
- DisposeGWorld(gwp);
- DisposeHandle((Handle)xh);
- return(0);
- }
- window2 = GetNewWindow(rWindow, (Ptr) window, (WindowPtr) -1);
- if (window2 == NULL) {
- DisposeGWorld(gwp);
- DisposePtr((Ptr)window);
- DisposeHandle((Handle)xh);
- return(0);
- }
- SetWRefCon(window2, (long)xh);
- (*xh)->rect = r;
- (*xh)->gwp = gwp;
- MoveWindow(window2, rg.left, rg.top, 0);
- SizeWindow(window2, rg.right-rg.left+kScrollbarAdjust, rg.bottom-rg.top+kScrollbarAdjust,0);
- name[name[0]+1] = 0;
- strcpy(&cc[1], &name[1]);
- if (l&0x80000000) {
- strcat(&cc[1], " (onboard)");
- } else {
- strcat(&cc[1], " (main memory)");
- }
- cc[0] = strlen(&cc[1]);
- SetWTitle(window2, cc);
- xoff += 20;
- yoff += 20;
- (*xh)->vScroll = GetNewControl(rVScroll, window2);
- (*xh)->hScroll = GetNewControl(rHScroll, window2);
- (*xh)->dx = 0;
- (*xh)->dy = 0;
- AdjustScrollbars(window2,1);
-
- if (convolved) {
- base = (unsigned char *)GetPixBaseAddr(pm);
- c = 1;
- SwapMMUMode(&c);
- rb = (*pm)->rowBytes&0x3ffe;
- p = base;
- for (i = (*pm)->bounds.left; i < (*pm)->bounds.right; i++) {
- p[1] = (((long)p[1]<<1)+0x80+p[rb+1])>>2;
- p[2] = (((long)p[2]<<1)+0x80+p[rb+2])>>2;
- p[3] = (((long)p[3]<<1)+0x80+p[rb+3])>>2;
- p += 4;
- }
- base = base + rb;
- for (j = (*pm)->bounds.top+1; j < ((*pm)->bounds.bottom-1); j++) {
- p = base;
- for (i = (*pm)->bounds.left; i < (*pm)->bounds.right; i++) {
- p[1] = (((long)p[1]<<1)+p[-rb+1]+p[rb+1])>>2;
- p[2] = (((long)p[2]<<1)+p[-rb+2]+p[rb+2])>>2;
- p[3] = (((long)p[3]<<1)+p[-rb+3]+p[rb+3])>>2;
- p += 4;
- }
- base = base + rb;
- }
- p = base;
- for (i = (*pm)->bounds.left; i < (*pm)->bounds.right; i++) {
- p[1] = (((long)p[1]<<1)+0x80+p[-rb+1])>>2;
- p[2] = (((long)p[2]<<1)+0x80+p[-rb+2])>>2;
- p[3] = (((long)p[3]<<1)+0x80+p[-rb+3])>>2;
- p += 4;
- }
- SwapMMUMode(&c);
- }
-
- ShowWindow(window2);
- return(1);
- }
-
- /* Check to see if a window belongs to the application. If the window pointer
- passed was NIL, then it could not be an application window. WindowKinds
- that are negative belong to the system and windowKinds less than userKind
- are reserved by Apple except for windowKinds equal to dialogKind, which
- mean it is a dialog. */
-
- #pragma segment Main
- Boolean IsAppWindow(window)
- WindowPtr window;
- {
- short windowKind;
-
- if ( window == nil )
- return false;
- else { /* application windows have windowKinds >= userKind (8) or dialogKind (2) */
- windowKind = ((WindowPeek) window)->windowKind;
- return (windowKind >= userKind) || (windowKind == dialogKind);
- }
- } /*IsAppWindow*/
-
-
- /* Check to see if a window belongs to a desk accessory. */
-
- #pragma segment Main
- Boolean IsDAWindow(window)
- WindowPtr window;
- {
- if ( window == nil )
- return false;
- else /* DA windows have negative windowKinds */
- return ((WindowPeek) window)->windowKind < 0;
- } /*IsDAWindow*/
-
-
- /* Check to see if a given trap is implemented. This is only used by the
- Initialize routine in this program, so we put it in the Initialize segment.
- The recommended approach to see if a trap is implemented is to see if
- the address of the trap routine is the same as the address of the
- Unimplemented trap. */
-
- #pragma segment Initialize
- Boolean TrapAvailable(tNumber,tType)
- short tNumber;
- TrapType tType;
- {
- /* Check and see if the trap exists. On 64K ROM machines, tType will be ignored. */
-
- return NGetTrapAddress(tNumber, tType) != GetTrapAddress(_Unimplemented);
- } /*TrapAvailable*/
-
-
- /* Display an alert that tells the user an error occurred, then exit the program.
- This routine is used as an ultimate bail-out for serious errors that prohibit
- the continuation of the application. Errors that do not require the termination
- of the application should be handled in a different manner. Error checking and
- reporting has a place even in the simplest application. The error number is used
- to index an 'STR#' resource so that a relevant message can be displayed. */
-
- #pragma segment Main
- void AlertUser()
- {
- short itemHit;
-
- SetCursor(&qd.arrow);
- itemHit = Alert(rUserAlert, nil);
- ExitToShell();
- } /* AlertUser */
-